#pragma once
#include <functional>
#include <type_traits>

#include "ClassFactory.h"

class ClassRegister
{
  public:
    ClassRegister(const std::string& classname, FactoryClass classobject)
    {
        Singleton<ClassFactory>::GetInstance()->registerClass(classname,
                                                              classobject);
    }

    ClassRegister(const std::string& classname,
                  const std::string& fieldname,
                  const std::string& fieldtype,
                  uintptr_t          offset)
    {
        Singleton<ClassFactory>::GetInstance()->registerClassField(
            classname, fieldname, fieldtype, offset);
    }

    ClassRegister(const std::string& classname,
                  const std::string& methodname,
                  uintptr_t          method)
    {
        Singleton<ClassFactory>::GetInstance()->registerClassMethod(
            classname, methodname, method);
    }
};

/* 类注册
ClassObject * co(){
    A * a = new A();
    a->setClassName("classname");
    return a;
}
ClassRegister register("classname", co);
*/
#define REGISTER_CLASS(CLASSNAME)                                              \
    ClassObject* BIN_CREATE_CLASS_##CLASSNAME()                                \
    {                                                                          \
        ClassObject* obj = new CLASSNAME();                                    \
        obj->set(#CLASSNAME);                                                  \
        return obj;                                                            \
    }                                                                          \
    ClassRegister CLASSREGISTER_##CLASSNAME(#CLASSNAME,                        \
                                            BIN_CREATE_CLASS_##CLASSNAME);

/* 类域成员变量注册
A a;
Register register("classname", "fieldname", "fieldtype",
    ((size_t)(&(a.fieldname)) - (size_t)(&a))
)
*/
#define REGISTER_CLASS_FIELD(CLASSNAME, FIELDNAME, FIELDTYPE)                  \
    CLASSNAME     BIN_CLASS_##FIELDNAME;                                       \
    ClassRegister CLASSREGISTER_CLASSFIELD_##FIELDNAME(                        \
        #CLASSNAME, #FIELDNAME, #FIELDTYPE,                                    \
        ((size_t)(&(BIN_CLASS_##FIELDNAME.FIELDNAME)) -                        \
         (size_t)(&BIN_CLASS_##FIELDNAME)));

/* 类域成员方法注册
        typedef std::function<void(decltype(this), int)>
            c_this_func;                // 类函数指针
        c_this_func cthisfunc_1 = f_f1; // 类函数指针对象（指向：函数指针）
        { //
   从宏定义到注册之间，存在函数指针传递，才可以获取函数指针并实现函数操作
            uintptr_t fun = (uintptr_t)&cthisfunc_1;
            (*((c_this_func*)fun))(this, 1);
        }
        cthisfunc_1(this, 1);
*/
#define REGISTER_CLASS_METHOD(CLASSNAME, METHODNAME)                           \
    std::function<void(CLASSNAME*, int)> BIN_CLASS_FUNC_##METHODNAME =         \
        &CLASSNAME::METHODNAME;                                                \
    ClassRegister CLASSREGISTER_CLASSMETHOD_##METHODNAME(                      \
        #CLASSNAME, #METHODNAME, (uintptr_t) & (BIN_CLASS_FUNC_##METHODNAME));
